package com.zmn.oms.zmn.business.impl.work;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.amount.AmountUtil;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.dms.common.dto.coup.dio.Prom.PromAlipayThirdCodeDIO;
import com.zmn.dms.common.dto.coup.dio.Prom.PromPayUseRecordMsgDIO;
import com.zmn.manager.mq.constant.MqTopicConsts;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.manager.redis.lock.DistributedLock;
import com.zmn.manager.redis.lock.DistributedLockUtils;
import com.zmn.mos.common.bo.pay.VoucherDetailBO;
import com.zmn.mos.common.utils.ClassConvertUtil;
import com.zmn.oms.business.interfaces.discount.OrderDiscountBService;
import com.zmn.oms.business.interfaces.messageV1.app.MessageSendAppService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.common.constant.LockConsts;
import com.zmn.oms.common.constant.MessageRuleIdConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderPayConsts;
import com.zmn.oms.common.dio.normal.orderadd.OrderPayDiscountDIO;
import com.zmn.oms.common.dro.orderpay.OrderPayResultDRO;
import com.zmn.oms.common.dto.OmsPayRequestDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.dto.acceptance.OrderWorkAcceptanceDTO;
import com.zmn.oms.model.entity.acceptance.OrderWorkAcceptance;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.discount.OrderPayDiscount;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.model.entity.visit.OrderVisit;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.acceptance.OrderWorkAcceptanceService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.orderpaydiscount.OrderPayDiscountService;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import com.zmn.oms.services.interfaces.visit.OrderVisitService;
import com.zmn.oms.services.interfaces.work.OrderWorkAmountService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.acceptance.OrderWorkAcceptanceBService;
import com.zmn.oms.zmn.business.interfaces.pay.OrderPayBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkAmountBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.pay.common.constant.PayConsts;
import com.zmn.pay.common.dto.PayResultDTO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：工单金额实现类型
 *
 * @author heciqi
 * @date 2018/11/7 14:47
 */
@Service
public class ZsOrderWorkAmountBServiceImpl implements ZsOrderWorkAmountBService {

	private Logger logger = LoggerFactory.getLogger(ZsOrderWorkAmountBServiceImpl.class);

	@Autowired
	OrderWorkAmountBService orderWorkAmountBService;

	@Autowired
	OrderWorkAmountService orderWorkAmountService;

	@Autowired
	OrderDiscountBService orderDiscountBService;

	@Autowired
	OrderWorkService orderWorkService;

	@Autowired
	OrderDetailService orderDetailService;

	@Autowired
	MessageSendAppService messageSendAppService;

	@Autowired
	OrderFactoryService orderFactoryService;

	@Autowired
	OrderPayBService orderPayBService;

	@Autowired
	OrderPayService orderPayService;

	@Autowired
	OrderPayDiscountService orderPayDiscountService;

	@Autowired
	OrderWorkAcceptanceBService orderWorkAcceptanceBService;
	@Autowired
	OrderWorkAcceptanceService orderWorkAcceptanceService;
	@Autowired
	OrderVisitService orderVisitService;
	@Autowired
	WorkFlowContextBService workFlowContextBService;
	@Autowired
	ZmnMQSender zmnMQSender;

	@NacosValue(value = "${pay.discount.ruleId:0}", autoRefreshed = true)
	private Integer payDiscountRuleId;

	@Value("${spring.mq.topic.dms:null}")
	private String DMS_MQ_TOPIC;

	private static final String PAY_DISCOUNT_KEY = "pay-discount-%s-%s";

	/**
	 * 更新定金支付
	 *
	 * @param orderPayResultDRO
	 */
	@Override
	public void updateDepositAmountPayResult(OrderPayResultDRO orderPayResultDRO) {
		String lockKey = String.format("%s", orderPayResultDRO.getOrderId());
		DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);
		logger.info("#ZsOrderWorkAmountBServiceImpl#updateDepositAmountPayResult 入参:{}", JSON.toJSONString(orderPayResultDRO));
		try {
			if (lock.tryLock()) {
				Integer duplicationOrderPay = orderPayBService.depositAndProgressAmountDuplicationOrderPay(orderPayResultDRO);// 是否重复支付
				orderPayResultDRO.setDuplicateType(duplicationOrderPay);
				// 未重复支付
				if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE)) {
					if (NumberUtil.isNullOrZero(orderPayResultDRO.getOrderPayId())) {
						// 2，插入支付记录
						orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);
						// 2，更新验收结果
						this.updateAcceptanceResult(orderPayResultDRO);
					} else {
						// 2，更新支付结果
						OrderPay orderPay = BeanMapper.map(orderPayResultDRO, OrderPay.class);
						orderPay.setOrderPayId(orderPayResultDRO.getOrderPayId());
						orderPay.setUpdater(StringUtils.defaultString(orderPayResultDRO.getOperator(), "系统"));
						orderPay.setDeleted(GlobalConsts.NO);
						orderPayService.updateByPrimaryKeySelective(orderPay);
						// 3，更新多次上门和验收结果
						this.updateAcceptance(orderPayResultDRO);
					}
					orderWorkAmountBService.updateDepositAmountPayResult(orderPayResultDRO);// 更新啄木鸟预收
				}
				// 重复支付-业务重复
				else if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ)) {
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入重复支付记录
					orderWorkAmountBService.addExceptionOrderPay(orderPayResultDRO);// 写入重复支付日志
				}
				// 重复支付-系统重复
				else {
					logger.info("{}系统重复或其他情况重复不处理", orderPayResultDRO.getWorkId());
				}
			}
		} catch (Exception e) {
			logger.error("updateDepositAmountPayResult异常:" + e.getMessage(), e);
		} finally {
			lock.unlock();
		}

		// 3，工单支付通知push推送
		OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());
		Map<String, Object> params = Maps.newHashMap();
		params.put("order_id", String.valueOf(orderPayResultDRO.getOrderId()));
		params.put("work_id", String.valueOf(orderPayResultDRO.getWorkId()));
		params.put("amount", String.valueOf(AmountUtil.fen2Yuan(orderPayResultDRO.getAmount()).doubleValue()));
		messageSendAppService.pushAppMessageInfo(MessageRuleIdConsts.PUSH_MSG_RULEID_ORDER_PAY, JSON.toJSONString(params), dbOrderWork);
	}

	/**
	 * 更新验收结果
	 * @param orderPayResultDRO
	 */
	private void updateAcceptance(OrderPayResultDRO orderPayResultDRO) {
		// 1，更新多次上门
		OrderVisit orderVisit = new OrderVisit();
		orderVisit.setOrderId(orderPayResultDRO.getOrderId());
		orderVisit.setOrderPayId(orderPayResultDRO.getOrderPayId());
		orderVisit.setAmount(orderPayResultDRO.getAmount());
		orderVisit.setAmountType(orderPayResultDRO.getAmountType());
		orderVisit.setPayStatus(orderPayResultDRO.getPayStatus());
		orderVisit.setUpdater(StringUtils.defaultString(orderPayResultDRO.getOperator(), "系统"));
		orderVisitService.updatePayStatusByKey(orderVisit);

		// 2，更新验收结果
		this.updateAcceptanceResult(orderPayResultDRO);
	}

	/**
	 * 更新验收结果
	 * @param orderPayResultDRO
	 */
	private void updateAcceptanceResult(OrderPayResultDRO orderPayResultDRO) {
		if (NumberUtil.isNotNullOrZero(orderPayResultDRO.getAcceptanceId())) {
			OrderWorkAcceptance dbAcceptance = orderWorkAcceptanceService.findOrderWorkAcceptanceByKeySrcMaster(orderPayResultDRO.getAcceptanceId(), orderPayResultDRO.getOrderId());
			if (Objects.equals(dbAcceptance.getAcceptanceResultStatus(), OrderConsts.ORDER_ACCEPTANCE_STATUS_WAIT)) {
				// 收到支付信息，定金确认，定金验收成功
				OrderWorkAcceptanceDTO dto = new OrderWorkAcceptanceDTO();
				dto.setOrderId(orderPayResultDRO.getOrderId());
				dto.setAcceptanceId(orderPayResultDRO.getAcceptanceId());
				dto.setAcceptanceResultStatus(OrderConsts.ORDER_ACCEPTANCE_STATUS_SUCCESS);
				dto.setOperator("用户");
				dto.setOperatorId(orderPayResultDRO.getOperatorId());
				dto.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
				dto.setOperateTime(DateUtil.getNow());
				try {
					orderWorkAcceptanceBService.modifyOrderWorkAcceptance(dto);
				} catch (OmsBaseException e) {
					logger.error("[{}]定金确认成功失败：[{}]", orderPayResultDRO.getOrderId(), e.getMessage());
				}
			}
		}
	}

	/**
	 * 更新进度款支付
	 *
	 * @param orderPayResultDRO
	 */
	@Override
	public void updateProgressAmountPayResult(OrderPayResultDRO orderPayResultDRO) {
		String lockKey = String.format("%s", orderPayResultDRO.getOrderId());
		DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);
		try {
			if (lock.tryLock()) {
				Integer duplicationOrderPay = orderPayBService.depositAndProgressAmountDuplicationOrderPay(orderPayResultDRO);// 是否重复支付
				orderPayResultDRO.setDuplicateType(duplicationOrderPay);
				// 未重复支付
				if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE)) {
					// 更新支付状态
					OrderPay orderPay = BeanMapper.map(orderPayResultDRO, OrderPay.class);
					orderPay.setOrderPayId(orderPayResultDRO.getOrderPayId());
					orderPay.setUpdater(StringUtils.defaultString(orderPayResultDRO.getOperator(), "系统"));
					orderPay.setDeleted(GlobalConsts.NO);
					logger.info("更新进度款，新支付信息：【{}】", JSON.toJSONString(orderPay));
					orderPayService.updateByPrimaryKeySelective(orderPay);

					OrderVisit orderVisit = new OrderVisit();
					orderVisit.setOrderId(orderPayResultDRO.getOrderId());
					orderVisit.setOrderPayId(orderPayResultDRO.getOrderPayId());
					orderVisit.setAmount(orderPayResultDRO.getAmount());
					orderVisit.setAmountType(orderPayResultDRO.getAmountType());
					orderVisit.setPayStatus(orderPayResultDRO.getPayStatus());
					orderVisit.setUpdater(StringUtils.defaultString(orderPayResultDRO.getOperator(), "系统"));
					orderVisitService.updatePayStatusByKey(orderVisit);

					orderWorkAmountBService.updateDepositAmountPayResult(orderPayResultDRO);// 更新啄木鸟预收
				}
				// 重复支付-业务重复
				else if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ)) {
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入重复支付记录
					orderWorkAmountBService.addExceptionOrderPay(orderPayResultDRO);// 写入重复支付日志
				}
				// 重复支付-系统重复
				else {
					logger.info("{}系统重复或其他情况重复不处理", orderPayResultDRO.getWorkId());
				}
			}
		} catch (Exception e) {
			logger.error("updateProgressAmountPayResult异常:" + e.getMessage(), e);
		} finally {
			lock.unlock();
		}

		// 3，工单支付通知push推送
		OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());
		Map<String, Object> params = Maps.newHashMap();
		params.put("order_id", String.valueOf(orderPayResultDRO.getOrderId()));
		params.put("work_id", String.valueOf(orderPayResultDRO.getWorkId()));
		params.put("amount", String.valueOf(AmountUtil.fen2Yuan(orderPayResultDRO.getAmount()).doubleValue()));
		messageSendAppService.pushAppMessageInfo(MessageRuleIdConsts.PUSH_MSG_RULEID_ORDER_PAY, JSON.toJSONString(params), dbOrderWork);
	}

	/**
	 * 更新工程师收款支付结果
	 * @param orderPayResultDRO
	 */
	@Override
	public void updateMasterAmountPayResult(OrderPayResultDRO orderPayResultDRO) {
		String lockKey = String.format("%s", orderPayResultDRO.getOrderId());
		DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);
		try {
			if (lock.tryLock()) {
				// 是否重复支付
				Integer duplicationOrderPay = orderPayBService.prepayAndMasterAmountDuplicationOrderPay(orderPayResultDRO);
				orderPayResultDRO.setDuplicateType(duplicationOrderPay);

				// 未重复支付
				if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE)) {
					orderWorkAmountBService.updateMasterAmountPayResult(orderPayResultDRO);// 更新师傅收款
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入支付记录
				}
				// 重复支付-业务重复
				else if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ)) {
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入重复支付记录
					orderWorkAmountBService.addExceptionOrderPay(orderPayResultDRO);// 写入重复支付日志
				}
				// 重复支付-系统重复
				else {
					logger.info("{}系统重复或其他情况重复不处理", orderPayResultDRO.getWorkId());
				}
			}
		} catch (Exception e) {
			logger.error("updateMasterAmountPayResult异常:" + e.getMessage(), e);
		} finally {
			lock.unlock();
		}

		// 3，工单支付通知push推送
		OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());
		Map<String, Object> params = Maps.newHashMap();
		params.put("order_id", String.valueOf(orderPayResultDRO.getOrderId()));
		params.put("work_id", String.valueOf(orderPayResultDRO.getWorkId()));
		params.put("amount", String.valueOf(AmountUtil.fen2Yuan(orderPayResultDRO.getAmount()).doubleValue()));
		messageSendAppService.pushAppMessageInfo(MessageRuleIdConsts.PUSH_MSG_RULEID_ORDER_PAY, JSON.toJSONString(params), dbOrderWork);
	}

	/**
	 * 更新优惠支付
	 *
	 * @param orderPayResultDRO
	 */
	@Override
	public void updateDiscountAmountPayResult(OrderPayResultDRO orderPayResultDRO) {
		String lockKey = String.format("%s", orderPayResultDRO.getOrderId());
		DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);

		try {
			if (lock.tryLock()) {
				// 是否重复支付
				Integer duplicationOrderPay = orderPayBService.channelPrepayAndDiscountAmountDuplicationOrderPay(orderPayResultDRO);
				orderPayResultDRO.setDuplicateType(duplicationOrderPay);
				if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE)) {
					// 插入渠道预付支付记录
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);
				}
				// 重复支付-业务重复
				else if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ)) {
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入渠道预付重复支付记录
					orderWorkAmountBService.addExceptionOrderPay(orderPayResultDRO);// 写入重复支付日志
				}
				// 重复支付-系统重复
				else {
					logger.info("{}优惠券系统重复或其他情况重复不处理", orderPayResultDRO.getWorkId());
				}
			}
		} catch (Exception e) {
			logger.error("updateDiscountAmountPayResult异常:" + e.getMessage(), e);
		} finally {
			lock.unlock();
		}
	}

	/**
	 * 更新渠道预付
	 *
	 * @param orderPayResultDRO
	 */
	@Override
	public void updateChannelPrepaidAmountPayResult(OrderPayResultDRO orderPayResultDRO) {
		String lockKey = String.format("%s", orderPayResultDRO.getOrderId());
		DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);

		OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());
		try {
			if (lock.tryLock()) {
				Date payTime = (dbOrderWork != null && Objects.nonNull(dbOrderWork.getCompleteTime())) ? dbOrderWork.getCompleteTime() : DateUtil.getNow();
				orderPayResultDRO.setPayTime(payTime);
				// 是否重复支付
				Integer duplicationOrderPay = orderPayBService.channelPrepayAndDiscountAmountDuplicationOrderPay(orderPayResultDRO);
				orderPayResultDRO.setDuplicateType(duplicationOrderPay);
				if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE)) {
					orderPayResultDRO.setDuplicateType(duplicationOrderPay);
					// 插入支付记录
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);
				}
				// 重复支付-业务重复
				else if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ)) {
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入重复支付记录
					orderWorkAmountBService.addExceptionOrderPay(orderPayResultDRO);// 写入重复支付日志
				}
				// 重复支付-系统重复
				else {
					logger.info("{}渠道预付系统重复或其他情况重复不处理", orderPayResultDRO.getWorkId());
				}
			}
		} catch (Exception e) {
			logger.error("updateChannelPrepaidAmountPayResult异常:" + e.getMessage(), e);
		} finally {
			lock.unlock();
		}
	}

	/**
	 * 更新啄木鸟预收
	 * @param orderPayResultDRO
	 */
	@Override
	public void updatePrepaidAmountPayResult(OrderPayResultDRO orderPayResultDRO) {
		String lockKey = String.format("%s", orderPayResultDRO.getOrderId());
		DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_AMOUNT + lockKey, LockConsts.LOCK_VALID_TIME);

		try {
			if (lock.tryLock()) {
				// 是否重复支付
				Integer duplicationOrderPay = orderPayBService.prepayAndMasterAmountDuplicationOrderPay(orderPayResultDRO);
				orderPayResultDRO.setDuplicateType(duplicationOrderPay);

				// 未重复支付
				if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_NONE)) {
					orderWorkAmountBService.updatePrepayAmountPayResult(orderPayResultDRO);// 更新啄木鸟预收
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入支付记录
				}
				// 重复支付-业务重复
				else if (Objects.equals(duplicationOrderPay, OrderPayConsts.ORDER_PAY_DUPLICATION_TYPE_BIZ)) {
					orderPayBService.insertOrderPay(orderPayResultDRO, duplicationOrderPay);// 插入重复支付记录
					orderWorkAmountBService.addExceptionOrderPay(orderPayResultDRO);// 写入重复支付日志
				}
				// 重复支付-系统重复
				else {
					logger.info("{}系统重复或其他情况重复不处理", orderPayResultDRO.getWorkId());
				}
			}
		} catch (Exception e) {
			logger.error("updateChannelPrepaidAmountPayResult异常:" + e.getMessage(), e);
		} finally {
			lock.unlock();
		}

		// 3，发送push通知
		OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());
		OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderPayResultDRO.getOrderId());
		String title = String.format("支付预付款成功%s元", AmountUtil.fen2Yuan(orderPayResultDRO.getAmount()).doubleValue());
		String message = String.format("%s-%s-%s", StringUtils.defaultString(orderDetail.getUserName()),
				StringUtils.defaultString(orderDetail.getTelephone()), StringUtils.defaultString(orderDetail.getAddress()));

		// 4，自动流转
		workFlowContextBService.asyncAutoFlow(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());
	}

	/**
	 * 更新退款支付结果
	 *
	 * @param payResultDTO
	 */
	@Override
	public void updateRefundPayResult(PayResultDTO payResultDTO) {
		OmsPayRequestDTO omsPayRequestDTO = JSON.parseObject(payResultDTO.getRequestData(), OmsPayRequestDTO.class);

		// 写入支付明细
		try {
			orderPayBService.insertOrderPay(payResultDTO);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	/**
	 * 保存支付优惠
	 * @param orderPayResultDRO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updatePayDiscountPayResult(OrderPayResultDRO orderPayResultDRO) {
		if (CollectionUtil.isNullOrEmpty(orderPayResultDRO.getDiscountGoods())) {
			return;
		}
		Map<String, String> discountMap = orderPayResultDRO.getDiscountGoods();

		String voucherListKey = "voucher_detail_list";

		if (!discountMap.containsKey(voucherListKey)) {
			// 没有优惠信息，返回
			return;
		}

		List<VoucherDetailBO> payDiscountBOList = ClassConvertUtil.convertStringToList(discountMap.get(voucherListKey), VoucherDetailBO.class);

		if (CollectionUtil.isNullOrEmpty(payDiscountBOList)) {
			return;
		}

		List<OrderPayDiscount> discountList = Lists.newArrayListWithCapacity(payDiscountBOList.size());
		Date now = DateUtil.getNow();

		for (VoucherDetailBO discount : payDiscountBOList) {

			if (Objects.equals(discount.getAmount(), discount.getOtherContribute())) {
				continue;
			}

			OrderPayDiscount payDiscount = BeanMapper.map(discount, OrderPayDiscount.class);
			// 设置金额为商家承担金额
			payDiscount.setAmount(payDiscount.getMerchantContribute());

			payDiscount.setCode(discount.getId());
			payDiscount.setOrderId(orderPayResultDRO.getOrderId());
			payDiscount.setCreater(org.apache.commons.lang.StringUtils.defaultString(orderPayResultDRO.getOperator(), "系统"));
			payDiscount.setCreateTime(now);

			discountList.add(payDiscount);
		}
		orderPayDiscountService.insertList(discountList);

		orderPayResultDRO.setOrderPayDiscountList(BeanMapper.mapList(discountList, OrderPayDiscountDIO.class));

		// 更新订单支付优惠金额
		OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());

		OrderWork updateOrderWork = new OrderWork();
		updateOrderWork.setOrderId(orderWork.getOrderId());
		updateOrderWork.setWorkId(orderWork.getWorkId());

		Integer payDiscountAmount = Optional.ofNullable(orderWork.getPayDiscountAmount()).orElse(0);
		Integer newPayDiscountAmount = discountList.stream().mapToInt(OrderPayDiscount::getAmount).sum();

		updateOrderWork.setPayDiscountAmount(payDiscountAmount + newPayDiscountAmount);

		orderWorkAmountService.updatePayDiscountAmount(updateOrderWork);

		try {
			this.sendPayDiscountMessageToDMS(orderPayResultDRO, discountList);
		} catch (Exception e) {
			logger.error("发送支付优惠信息失败", e);
		}


	}

	/**
	 * 发送优惠信息给DMS
	 */
	private void sendPayDiscountMessageToDMS(OrderPayResultDRO orderPayResultDRO, List<OrderPayDiscount> discountList) {
		if (CollectionUtil.isNullOrEmpty(discountList)) {
			return;
		}
		PromPayUseRecordMsgDIO recordMsgDIO = new PromPayUseRecordMsgDIO();
		recordMsgDIO.setOrderId(orderPayResultDRO.getOrderId());
		recordMsgDIO.setPayChannelId(orderPayResultDRO.getPayChannelId());
		recordMsgDIO.setPromId(payDiscountRuleId);
		recordMsgDIO.setUseTime(DateUtil.getNow());
		recordMsgDIO.setPayTradeNo(orderPayResultDRO.getInnerTradeNo());

		List<PromAlipayThirdCodeDIO> thirdCodeDIOList = discountList.stream()
				.map(discount -> new PromAlipayThirdCodeDIO(discount.getAmount(), discount.getCode())).collect(Collectors.toList());
		recordMsgDIO.setPromAlipayThirdCodeDIOS(thirdCodeDIOList);

		String key = String.format(PAY_DISCOUNT_KEY, orderPayResultDRO.getAmountType(), orderPayResultDRO.getOrderId());
		String message = JSON.toJSONString(recordMsgDIO);
		logger.info("发送支付优惠信息给DMS key:{}, content:{}", key, message);
		zmnMQSender.send(DMS_MQ_TOPIC, "pay_discount", key, message);
	}
}
